﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using COFE.Core.Filter;
using COFE.Data.Utils.ThirdParty;
using System.Linq.Expressions;

namespace COFE.Data.Filter
{

    /// <summary>
    /// Define an expression so EnumerateFSIs() method can poll entries directly from table.
    /// </summary>
    public abstract class EntryFilterExpression<T> :
        IEntryFilterExpression<IEntryFilter>
        where T : IEntryFilter
    {
        #region Constructor


       protected EntryFilterExpression()          
        {            
            _supportedType = typeof(T);
            //if (_supportedType.GetInterface(typeof(T).Name) == null)
            //    throw new ArgumentException("Type");            
        }

     

        #endregion

        #region Methods


       public abstract Expression<Func<Entry, bool>>
           getExpression(IEntryFilter entryFilter, IOptionFilter[] options);

       public virtual Expression<Func<Entry, bool>>
          getOutputExpression(IEntryFilter entryFilter, IOptionFilter[] options)
       {
           return e => true;
       }

       public Expression<Func<Entry, bool>> GetQueryExpression(IEntryFilter entryFilter, IOptionFilter[] options)
       {
          return getExpression(entryFilter, options);
       }

       public Expression<Func<Entry, bool>> GetQueryOutputExpression(IEntryFilter entryFilter, IOptionFilter[] options)
       {
           return getOutputExpression(entryFilter, options);
       }

       public virtual IQueryable<Entry> ProcessQuery(IQueryable<Entry> input,
           IEntryFilter filter, IOptionFilter[] options)
       {
           return input.Where(GetQueryExpression(filter, options));
       }

       public virtual IEnumerable<Entry> ProcessQueryOutput(IEnumerable<Entry> input,
          IEntryFilter filter, IOptionFilter[] options)
       {
           return input.Where(GetQueryOutputExpression(filter, options).Compile());
       }


        #endregion

        #region Data

        private Type _supportedType;

        #endregion

        #region Public Properties

        public Type SupportedType { get { return _supportedType; } }

        #endregion       
    }
}
